package com.zy.business.service.impl;

import cn.hutool.core.convert.Convert;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageInfo;
import com.zy.business.domain.*;
import com.zy.business.mapper.*;
import com.zy.business.service.AbsenceService;
import com.zy.business.service.PunchCardService;
import com.zy.business.service.ShiftService;
import com.zy.common.annotation.DataScope;
import com.zy.common.constant.HttpStatus;
import com.zy.common.core.domain.AjaxResult;
import com.zy.common.core.domain.entity.SysUser;
import com.zy.common.core.page.TableDataInfo;
import com.zy.common.utils.DateUtil;
import com.zy.common.utils.*;
import com.zy.system.mapper.SysUserMapper;
import com.zy.system.service.ISysUserService;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description:
 * @author: whf
 * @create: 2022-07-30 09:35
 **/
@Service
public class PunchCardServiceImpl extends ServiceImpl<PunchCardMapper, TbPunchCard> implements PunchCardService {

    @Resource
    private SysUserMapper userMapper;

    @Value("${PUNCHCARD_REMIND}")
    private String TEMPLATEID;

    @Value("${PUNCHCARD_SUCCESS}")
    private String successTEMPLATEID;

    @Value("${APPID}")
    private String APPID;

    @Value("${APPSECRET}")
    private String APPSECRET;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private HolidayMapper holidayMapper;

    @Autowired
    private AbsenceMapper absenceMapper;

    @Autowired
    private ShiftService tbShiftService;

    @Autowired
    private AttendanceMapper attendanceMapper;

    @Autowired
    private ReportBackMapper reportBackMapper;

    @Autowired
    private AbsenceService absenceService;

    @Override
    public List<TbPunchCard> getList(){
        List<TbPunchCard> punchCards = this.baseMapper.list();
        SimpleDateFormat sp=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal= Calendar.getInstance();
        cal.add(Calendar.DATE,-1);
        Date d=cal.getTime();
        String yesterday=sp.format(d);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        String monthFirstDay = sp.format(cal.getTime());
        for(TbPunchCard punchCard:punchCards){
            Long total = this.baseMapper.monthCount(monthFirstDay,yesterday,punchCard.getUserId(),null);
            Long normal = this.baseMapper.monthCount(monthFirstDay,yesterday,punchCard.getUserId(),4);
            String attendance = "";
            if(total==0L){
                attendance = "0.0%";
            }else{
                attendance = String.format("%.1f",normal.doubleValue()*100/total.doubleValue())+"%";
            }
            punchCard.setAttendance(attendance);
        }
        return punchCards;
    }

    @Override
    public List<Map<String, Object>> getListByDate(Long userId, String date){
        if (StringUtils.isEmpty(date)){
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            date = sdf.format(new Date());
        }
        List<Map<String, Object>> punchCards = this.baseMapper.getListByDate(userId,date);
        return punchCards;
    }

    @Override
    public List<Map<String, Object>> getListByDateRemind(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String date = sdf.format(new Date());
        List<Map<String, Object>> punchCards = this.baseMapper.getListByDateRemind(null,date);
        return punchCards;
    }

    @Override
    public TbPunchCard getLastPunchCard(String userId){
        TbPunchCard punchCard = this.baseMapper.getLastPunchCard(userId);
        return  punchCard;
    }

    /** 打卡提醒 **/
    @Override
    public AjaxResult sendMessage(String openid, String remarkStr){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SysUser user = userMapper.getUserByOpenId(openid);
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", user.getOpenId());   // openid
        jsonObject.put("template_id", TEMPLATEID);
        jsonObject.put("url", "http://kq.heshenghua.net/dkH5");
        /**
         * {{first.DATA}}
         * 姓名：{{keyword1.DATA}}
         * 时间：{{keyword2.DATA}}
         * 状态：{{keyword3.DATA}}
         * {{remark.DATA}}
         */
        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", "您好，您有一条考勤打卡提醒");
        first.put("color", "#173177");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", user.getUserName());
        keyword1.put("color", "#173177");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", sdf.format(new Date()));
        keyword2.put("color", "#173177");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", "未打卡");
        keyword3.put("color", "#173177");
        JSONObject remark = new JSONObject();
        remark.put("value", remarkStr);
        remark.put("color", "#173177");

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
        return AjaxResult.success();
    }

    /** 打卡成功通知 **/
    @Override
    public AjaxResult sendSuccessMessage(TbPunchCard punchCard){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        SysUser user = userMapper.selectUserById(punchCard.getUserId());
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", user.getOpenId());   // openid
        jsonObject.put("template_id", successTEMPLATEID);
        jsonObject.put("url", "http://kq.heshenghua.net/dkH5/#/");
        /**
         * {{first.DATA}}
         * 打卡人：{{keyword1.DATA}}
         * 打卡地点：{{keyword2.DATA}}
         * 打卡方式：{{keyword3.DATA}}
         * 打卡时间：{{keyword4.DATA}}
         * {{remark.DATA}}
         */

        String firstStr = "";
        if (punchCard.getState()==1 || punchCard.getState()==3){
            firstStr = "上班打卡成功！";
        }else {
            firstStr = "下班打卡成功！";
        }
        String address = "";
        String keyStr3 = "";
        if ("OUT".equals(punchCard.getPunchCardType())){
            keyStr3 = "外勤打卡";
        }else if ("HK".equals(punchCard.getPunchCardType())){
            keyStr3 = "内勤（门禁）打卡";
        }else if ("CAMERA".equals(punchCard.getPunchCardType())){
            keyStr3 = "内勤（摄像头）打卡";
        }else {
            keyStr3 = "内勤打卡";
        }
        if (StringUtils.isEmpty(punchCard.getAddress())){
            address = "新岛科技园";
        }else {
            address = punchCard.getAddress();
        }
        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", firstStr);
        first.put("color", "#173177");
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", user.getUserName());
        keyword1.put("color", "#173177");
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", address);
        keyword2.put("color", "#173177");
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", keyStr3);
        keyword3.put("color", "#173177");
        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", sdf.format(punchCard.getPunchCardTime()));
        keyword4.put("color", "#173177");
        JSONObject remark = new JSONObject();
        remark.put("value", "点击查看详情");
        remark.put("color", "#173177");

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("keyword4",keyword4);
        //data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
        return AjaxResult.success();
    }

    @Override
    public Map<String, Object> getCurrentRecord(Long userId) {
        Map<String, Object> map = new HashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String monthStart = DateUtil.getMonthStart();
        String currentDate = sdf.format(new Date());
        List<String> days = DateUtil.getDays(monthStart, currentDate);
        Integer attendanceNum = 0;
        Integer beLateNum = 0;
        Integer missNum = 0;
        for (String day : days) {
            List<TbPunchCard> punchCardList = baseMapper.getUserListByDate(userId,day);
            if (punchCardList!=null && punchCardList.size()>0){
                Boolean sign = false;
                for (TbPunchCard punchCard : punchCardList) {
                    //状态(0:未打卡1:缺卡2:迟到3:请假4:正常)
                    if (punchCard.getStatus()==2){
                        beLateNum ++;
                    }
                    if (punchCard.getStatus()==1){
                        missNum ++;
                    }
                    if (punchCard.getStatus()==2 || punchCard.getStatus()==4){
                        sign = true;
                    }
                }
                if (sign){
                    attendanceNum ++;
                }
            }
        }
        map.put("attendanceNum",attendanceNum);
        map.put("beLateNum",beLateNum);
        map.put("missNum",missNum);
        return map;
    }

    @Override
    public List<Map<String, Object>> getUserMonthData(String month, Long userId) {
        String firstDay = "";
        String lastDay = "";
        if (userId==null){
            userId = SecurityUtils.getUserId();
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        String currentMonth = sdf.format(new Date());
        if(!month.equals(currentMonth)){
            firstDay = DateUtil.giveMonthFist(month);
            lastDay = DateUtil.giveMonthLast(firstDay);
        }else{
            firstDay = DateUtil.giveMonthFist(currentMonth);
            lastDay = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        }
        List<String> days = DateUtil.getDays(firstDay,lastDay);
        List<Map<String,Object>> dataList = new ArrayList<>();
        if(days!=null && days.size()>0){
            for(String dayStr:days){
                Map<String,Object> dataMap = new HashMap<>();
                Integer workday = holidayMapper.getIsHoliday(dayStr);
                dataMap.put("date",dayStr);
                Integer type = 0;
                List<Map<String,Object>> punchCards = baseMapper.getListByDate(userId,dayStr);
                if(punchCards!=null && punchCards.size()>0){
                    for(Map map:punchCards){
                        if(Integer.parseInt(map.get("status").toString())!=4){
                            type = 1;
                        }
                    }
                }else{
                    type = 1;
                }
                dataMap.put("workday",workday);
                dataMap.put("type",type);
                dataList.add(dataMap);
            }
        }
        return dataList;
    }

    @Override
    public TableDataInfo getDeptAttendance(String month, String name) {
        SysUser sysUser = new SysUser();
        if (StringUtils.isNotEmpty(name)){
            sysUser.setUserName(name);
        }
        try {
            PageUtils.startPage();
            List<String> userList = userService.getUserIdList(sysUser);
            String firstDay = "";
            String lastDay = "";
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm");
            SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            TbShift shift = tbShiftService.selectTbShiftById();//获取排班
            String currentMonth = sdf.format(new Date());
            if(!month.equals(currentMonth)){
                firstDay = DateUtil.giveMonthFist(month);
                lastDay = DateUtil.giveMonthLast(firstDay);
            }else{
                firstDay = DateUtil.giveMonthFist(currentMonth);
                lastDay = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            }
            Integer days = holidayMapper.getWorkDayNum(firstDay,lastDay);
            List<Map<String, Object>> dataList= new ArrayList<>();
            if(userList!=null && userList.size()>0){
                for(String userId:userList){
                    Long userid = Long.parseLong(userId);
                    SysUser user = userService.selectUserById(userid);
                    Map<String, Object> map = new HashMap<>();
                    map.put("userName",user.getUserName());
                    map.put("userId",userId);
                    map.put("dingUserId",user.getDingUserId());
                    map.put("dayNum",days);
                    Long beLate = baseMapper.monthCount(firstDay,lastDay,userid,2);
                    map.put("lateNum",beLate);
                    Long missingCard = baseMapper.monthCount(firstDay,lastDay,userid,1);
                    map.put("missNum",missingCard);
                    //Double absenceNum = absenceMapper.getDurationTotal(userid,firstDay,lastDay);
                    List<TbAbsence> absenceList = absenceMapper.getUserList(user.getUserId(),firstDay,lastDay);
                    Double absenceNum = 0d;
                    for (TbAbsence absence : absenceList) {
                        if(absence.getState()==5){
                            TbReportBack reportBack = reportBackMapper.selectOne(new QueryWrapper<TbReportBack>().eq("absence_id",absence.getAbsenceId()));
                            absence.setEndTime(reportBack.getReportBackTime());
                        }
                        if (DateUtil.boolcompara(sdf1.format(absence.getStartTime()),firstDay) && DateUtil.boolcompara(lastDay,sdf1.format(absence.getEndTime()))){
                            absenceNum += Double.valueOf(absenceService.getDuration(sdf3.format(absence.getStartTime()), sdf3.format(absence.getEndTime())));
                        } else if (DateUtil.boolcompara(firstDay,sdf1.format(absence.getStartTime())) && DateUtil.boolcompara(lastDay,sdf1.format(absence.getEndTime()))){
                            absenceNum += Double.valueOf(absenceService.getDuration(firstDay + " 00:00:00", sdf3.format(absence.getEndTime())));
                        }else if (DateUtil.boolcompara(sdf1.format(absence.getStartTime()),firstDay) && DateUtil.boolcompara(sdf1.format(absence.getEndTime()),lastDay)){
                            absenceNum += Double.valueOf(absenceService.getDuration(sdf3.format(absence.getStartTime()), lastDay+" 23:59:59"));
                        }
                    }
                    map.put("absenceNum",absenceNum);
                    dataList.add(map);
                }
            }
            TableDataInfo rspData = new TableDataInfo();
            rspData.setCode(HttpStatus.SUCCESS);
            rspData.setMsg("查询成功");
            rspData.setRows(dataList);
            rspData.setTotal(new PageInfo(userList).getTotal());
            return rspData;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }

    }

    @Override
    public List<TbPunchCard> getByStatus(Integer status, Integer state, Integer isRemind) {
        List<TbPunchCard> punchCards = this.baseMapper.getByStatus(status,state,isRemind);
        return punchCards;
    }

    @Override
    public void exportReport(String beginDate, String endDate, HttpServletResponse response) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat sdf1 = new SimpleDateFormat("MM-dd");
            SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm");
            SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFRow row = null;
            HSSFCell cell = null;
            // 建立新的sheet对象（excel的表单） 并设置sheet名字
            HSSFSheet sheet = wb.createSheet(beginDate+"至"+endDate+"考勤信息");
            sheet.setDefaultRowHeightInPoints(30);// 设置缺省列高sheet.setDefaultColumnWidth(20);//设置缺省列宽
            sheet.setDefaultColumnWidth(10);
            //----------------标题样式---------------------
            HSSFCellStyle titleStyle = wb.createCellStyle();        //标题样式
            titleStyle.setAlignment(HorizontalAlignment.CENTER);
            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            Font ztFont = wb.createFont();
            ztFont.setItalic(false);                     // 设置字体为斜体字
            ztFont.setColor(Font.COLOR_NORMAL);            // 将字体设置为“红色”
            ztFont.setFontHeightInPoints((short)16);    // 将字体大小设置为18px
            ztFont.setFontName("宋体");             // 将“宋体”字体应用到当前单元格上
            ztFont.setBold(true);    //加粗
            titleStyle.setFont(ztFont);

            //----------------二级标题格样式----------------------------------
            HSSFCellStyle titleStyle2 = wb.createCellStyle();        //表格样式
            titleStyle2.setAlignment(HorizontalAlignment.CENTER);
            titleStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
            Font ztFont2 = wb.createFont();
            ztFont2.setItalic(false);                     // 设置字体为斜体字
            ztFont2.setColor(Font.COLOR_NORMAL);            // 将字体设置为“红色”
            ztFont2.setFontHeightInPoints((short)11);    // 将字体大小设置为18px
            ztFont2.setFontName("宋体");             // 字体应用到当前单元格上
            ztFont2.setBold(true);     //加粗
            //ztFont.setUnderline(Font.U_DOUBLE);         // 添加（Font.U_SINGLE单条下划线/Font.U_DOUBLE双条下划线）
            //ztFont.setStrikeout(true);                  // 是否添加删除线
            titleStyle2.setFont(ztFont2);

            //----------------单元格样式----------------------------------
            HSSFCellStyle cellStyle = wb.createCellStyle();        //表格样式
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle.setBorderRight(BorderStyle.THIN);//右边框
            Font cellFont = wb.createFont();
            cellFont.setItalic(false);                     // 设置字体为斜体字
            cellFont.setColor(Font.COLOR_NORMAL);            // 将字体设置为“红色”
            cellFont.setFontHeightInPoints((short)10);    // 将字体大小设置为18px
            cellFont.setFontName("宋体");             // 字体应用到当前单元格上
            //cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            cellStyle.setFont(cellFont);
            cellStyle.setWrapText(true);//设置自动换行
            //----------------------------------------------------------

            //----------------单元格样式(迟到)----------------------------------
            HSSFCellStyle cellStyle1 = wb.createCellStyle();        //表格样式
            cellStyle1.setAlignment(HorizontalAlignment.CENTER);
            cellStyle1.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle1.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle1.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle1.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle1.setBorderRight(BorderStyle.THIN);//右边框
            cellStyle1.setFont(cellFont);
            cellStyle1.setWrapText(true);//设置自动换行
            //设置背景颜色
            cellStyle1.setFillForegroundColor(IndexedColors.ORANGE.getIndex());
            //solid 填充 foreground 前景色
            cellStyle1.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            //----------------------------------------------------------

            //----------------单元格样式(缺卡)----------------------------------
            HSSFCellStyle cellStyle2 = wb.createCellStyle();        //表格样式
            cellStyle2.setAlignment(HorizontalAlignment.CENTER);
            cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle2.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle2.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle2.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle2.setBorderRight(BorderStyle.THIN);//右边框
            cellStyle2.setFont(cellFont);
            cellStyle2.setWrapText(true);//设置自动换行
            //设置背景颜色
            cellStyle2.setFillForegroundColor(IndexedColors.RED.getIndex());
            //solid 填充 foreground 前景色
            cellStyle2.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            //----------------------------------------------------------
            List<String> userList = userService.getUserIdList(new SysUser());
            List<TbHoliday> holidayList = holidayMapper.getListBybetween(beginDate,endDate);

            // ----------------------创建第一行---------------
            // 在sheet里创建第一行，参数为行索引(excel的行)，可以是0～65535之间的任何一个
            row = sheet.createRow(0);
            // 创建单元格（excel的单元格，参数为列索引，可以是0～255之间的任何一个
            cell = row.createCell(0);
            // 合并单元格CellRangeAddress构造参数依次表示起始行，截至行，起始列， 截至列
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, holidayList.size()+6));
            // 设置单元格内容
            cell.setCellValue(beginDate+"至"+endDate+"考勤统计");
            cell.setCellStyle(titleStyle);
            // ----------------------创建第二行（表头）---------------
            String startTime = sdf.format(holidayList.get(0).getDate());
            String endTime = sdf.format(holidayList.get(holidayList.size()-1).getDate());
            TbShift shift = tbShiftService.selectTbShiftById();//获取排班
            for(int j=1;j<=userList.size()+1;j++){
                row = sheet.createRow(j);
                SysUser user = null;
                List<TbAbsence> absenceList = null;
                if(j>=2){
                    user = userMapper.selectUserById(Long.parseLong(userList.get(j-2)));
                    absenceList = absenceMapper.getUserList(user.getUserId(),startTime,endTime);
                }
                Map<String,Double> absenceMap = new HashMap<>();
                Map<String,Double> sabbaticalMap = new HashMap<>();
                int normal = 0;//正常出勤天数
                Double totalHours = 0d;//总请假小时数
                Double totalSabbatical = 0d;
                int lateNum = 0;//迟到次数
                int missNum = 0;//缺卡次数
                if(absenceList!=null && absenceList.size()>0){
                    for(TbAbsence absence:absenceList){
                        if(absence.getState()==5){
                            TbReportBack reportBack = reportBackMapper.selectOne(new QueryWrapper<TbReportBack>().eq("absence_id",absence.getAbsenceId()));
                            absence.setEndTime(reportBack.getReportBackTime());
                            absence.setAbsenceDuration(absence.getActualAbsence()+absence.getActualSabbatical());
                            absence.setSabbaticalHour(absence.getActualSabbatical());
                        }
                        if(sdf.format(absence.getStartTime()).equals(sdf.format(absence.getEndTime()))){
                            if(absenceMap.get(sdf.format(absence.getStartTime()))==null){
                                absenceMap.put(sdf.format(absence.getStartTime()),absence.getAbsenceDuration());
                            }else {
                                BigDecimal b1 = new BigDecimal(absenceMap.get(sdf.format(absence.getStartTime())).toString());
                                BigDecimal b2 = new BigDecimal(absence.getAbsenceDuration().toString());
                                absenceMap.put(sdf.format(absence.getStartTime()),new Double(b1.add(b2).doubleValue()));
                            }
                            if (sabbaticalMap.get(sdf.format(absence.getStartTime()))==null){
                                sabbaticalMap.put(sdf.format(absence.getStartTime()),absence.getSabbaticalHour());
                            }else {
                                BigDecimal b1 = new BigDecimal(sabbaticalMap.get(sdf.format(absence.getStartTime())).toString());
                                BigDecimal b2 = new BigDecimal(absence.getSabbaticalHour().toString());
                                sabbaticalMap.put(sdf.format(absence.getStartTime()),new Double(b1.add(b2).doubleValue()));
                            }
                            if(shift.getStartTime1().compareTo(sdf2.format(absence.getStartTime()))>=0){
                                TbPunchCard punchCard = baseMapper.getPunchCardByStateAndDate(user.getUserId(),sdf.format(absence.getStartTime()),1);
                                punchCard.setStatus(3);
                                this.updateById(punchCard);
                            }
                            if(shift.getEndTime1().compareTo(sdf2.format(absence.getStartTime()))>0 && shift.getEndTime1().compareTo(sdf2.format(absence.getEndTime()))<=0){
                                TbPunchCard punchCard = baseMapper.getPunchCardByStateAndDate(user.getUserId(),sdf.format(absence.getStartTime()),2);
                                punchCard.setStatus(3);
                                this.updateById(punchCard);
                            }
                            if(shift.getStartTime2().compareTo(sdf2.format(absence.getStartTime()))>=0 && shift.getStartTime2().compareTo(sdf2.format(absence.getEndTime()))<0){
                                TbPunchCard punchCard = baseMapper.getPunchCardByStateAndDate(user.getUserId(),sdf.format(absence.getStartTime()),3);
                                punchCard.setStatus(3);
                                this.updateById(punchCard);
                            }
                            if(shift.getEndTime2().compareTo(sdf2.format(absence.getEndTime()))<=0){
                                TbPunchCard punchCard = baseMapper.getPunchCardByStateAndDate(user.getUserId(),sdf.format(absence.getStartTime()),4);
                                punchCard.setStatus(3);
                                this.updateById(punchCard);
                            }
                        }else{
                            Double absenceDuration = 0d;
                            //判断请假开始时间
                            System.out.println(sdf2.format(absence.getStartTime()));
                            if(shift.getStartTime1().compareTo(sdf2.format(absence.getStartTime()))>=0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getStartTime()), Convert.toIntArray("1,2,3,4"));
                            }else if(shift.getStartTime1().compareTo(sdf2.format(absence.getStartTime()))<0 && shift.getEndTime1().compareTo(sdf2.format(absence.getStartTime()))>0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getStartTime()),Convert.toIntArray("2,3,4"));
                            }else if(shift.getStartTime2().compareTo(sdf2.format(absence.getStartTime()))==0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getStartTime()),Convert.toIntArray("3,4"));
                            }else if(shift.getStartTime2().compareTo(sdf2.format(absence.getStartTime()))<0 && shift.getEndTime2().compareTo(sdf2.format(absence.getStartTime()))>0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getStartTime()),Convert.toIntArray("4"));

                            }
                            absenceDuration = Double.valueOf(absenceService.getDuration(sdf3.format(absence.getStartTime()),sdf.format(absence.getStartTime())+" "+shift.getEndTime2()));
                            //给请假开始日期赋值小时数
                            if(absenceMap.get(sdf.format(absence.getStartTime()))==null){
                                absenceMap.put(sdf.format(absence.getStartTime()),absenceDuration);
                            }else {
                                BigDecimal b1 = new BigDecimal(absenceMap.get(sdf.format(absence.getStartTime())).toString());
                                BigDecimal b2 = new BigDecimal(absenceDuration.toString());
                                absenceMap.put(sdf.format(absence.getStartTime()),new Double(b1.add(b2).doubleValue()));
                            }
                            //判断请假结束时间
                            if(shift.getStartTime1().compareTo(sdf2.format(absence.getEndTime()))<0 && shift.getEndTime1().compareTo(sdf2.format(absence.getEndTime()))>0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getEndTime()),Convert.toIntArray("1"));
                            }else if(shift.getEndTime1().compareTo(sdf2.format(absence.getEndTime()))==0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getEndTime()),Convert.toIntArray("1,2"));
                            }else if(shift.getStartTime2().compareTo(sdf2.format(absence.getEndTime()))<0 && shift.getEndTime2().compareTo(sdf2.format(absence.getEndTime()))>0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getEndTime()),Convert.toIntArray("1,2,3"));
                            }else if(shift.getEndTime2().compareTo(sdf2.format(absence.getEndTime()))==0){
                                baseMapper.updateByDate(user.getUserId(),sdf.format(absence.getEndTime()),Convert.toIntArray("1,2,3,4"));
                            }
                            if (absence.getSabbaticalHour()<=absenceDuration){
                                if (sabbaticalMap.get(sdf.format(absence.getStartTime()))==null){
                                    sabbaticalMap.put(sdf.format(absence.getStartTime()),absence.getSabbaticalHour());
                                }else {
                                    BigDecimal b1 = new BigDecimal(sabbaticalMap.get(sdf.format(absence.getStartTime())).toString());
                                    BigDecimal b2 = new BigDecimal(absence.getSabbaticalHour().toString());
                                    sabbaticalMap.put(sdf.format(absence.getStartTime()),new Double(b1.add(b2).doubleValue()));
                                }
                            }else {
                                sabbaticalMap.put(sdf.format(absence.getStartTime()),absenceDuration);
                                BigDecimal b1 = new BigDecimal(absence.getSabbaticalHour().toString());
                                BigDecimal b2 = new BigDecimal(absenceDuration.toString());
                                Double diffTxHours = new Double(b1.subtract(b2).doubleValue());
                                Double t = diffTxHours%7.5;
                                Double x = diffTxHours/7.5;
                                int c = x.intValue();
                                if(t==0){
                                    if(c>=1){
                                        int i=1;
                                        String date = sdf.format(absence.getStartTime());
                                        while (i<=c){
                                            date = DateUtil.addDay(date);
                                            if(sdf.parse(date).getTime()>sdf.parse(endTime).getTime()){
                                                break;
                                            }
                                            int type = holidayMapper.getIsHoliday(date);
                                            while (type==2){
                                                date = DateUtil.addDay(date);
                                                type=holidayMapper.getIsHoliday(date);
                                            }
                                            sabbaticalMap.put(date,7.5);
                                            i++;
                                        }
                                    }
                                }else{
                                    if(c>=1){
                                        int i=1;
                                        String date = sdf.format(absence.getStartTime());
                                        while (i<=c){
                                            date = DateUtil.addDay(date);
                                            int type = holidayMapper.getIsHoliday(date);
                                            while (type==2){
                                                date = DateUtil.addDay(date);
                                                type=holidayMapper.getIsHoliday(date);
                                            }
                                            sabbaticalMap.put(date,7.5);
                                            i++;
                                        }
                                    }
                                    sabbaticalMap.put(sdf.format(absence.getEndTime()),t);
                                }
                            }
                            //给请假结束日期赋值小时数
                            Double endAbsenceDuration = 0d;
                            BigDecimal b1 = new BigDecimal(absence.getAbsenceDuration().toString());
                            BigDecimal b2 = new BigDecimal(absenceDuration.toString());
                            Double diffHours = new Double(b1.subtract(b2).doubleValue());
                            Double d = diffHours%7.5;
                            Double a = diffHours/7.5;
                            int b = a.intValue();
                            if(d==0){
                                endAbsenceDuration = 7.5d;
                                if(b>=1){
                                    int i=1;
                                    String date = sdf.format(absence.getStartTime());
                                    while (i<=b){
                                        date = DateUtil.addDay(date);
                                        if(sdf.parse(date).getTime()>sdf.parse(endTime).getTime()){
                                            break;
                                        }
                                        int type = holidayMapper.getIsHoliday(date);
                                        while (type==2){
                                            date = DateUtil.addDay(date);
                                            type=holidayMapper.getIsHoliday(date);
                                        }
                                        baseMapper.updateByDate(user.getUserId(),date, Convert.toIntArray("1,2,3,4"));
                                        absenceMap.put(date,7.5);
                                        i++;
                                    }
                                }
                            }else{
                                endAbsenceDuration = d;
                                if(b>=1){
                                    int i=1;
                                    String date = sdf.format(absence.getStartTime());
                                    while (i<=b){
                                        date = DateUtil.addDay(date);
                                        int type = holidayMapper.getIsHoliday(date);
                                        while (type==2){
                                            date = DateUtil.addDay(date);
                                            type=holidayMapper.getIsHoliday(date);
                                        }
                                        baseMapper.updateByDate(user.getUserId(),date,Convert.toIntArray("1,2,3,4"));
                                        absenceMap.put(date,7.5);
                                        i++;
                                    }
                                }
                            }
                            if((absenceMap.get(sdf.format(absence.getEndTime()))==null || endAbsenceDuration==7.5)){
                                if (shift.getStartTime1().compareTo(sdf2.format(absence.getEndTime()))<0){
                                    absenceMap.put(sdf.format(absence.getEndTime()),endAbsenceDuration);
                                }
                            }else {
                                absenceMap.put(sdf.format(absence.getEndTime()),absenceMap.get(sdf.format(absence.getEndTime()))+endAbsenceDuration);
                            }
                        }
                    }
                    System.out.println(user.getName()+"---请假时长:"+absenceMap);
                    System.out.println(user.getName()+"---调休时长:"+sabbaticalMap);
                    //cell.setCellValue(StringUtils.isEmpty(msg)?"√":msg);
                }
                /*if (reportBackList!=null && reportBackList.size()>0){
                    for (TbReportBack reportBack : reportBackList) {
                        absenceService.updateAbsence(user.getUserId(),reportBack.getReportBackTime(),reportBack.getEndTime());
                    }
                }*/
                for(int i=0;i<=holidayList.size()+6;i++){
                    cell = row.createCell(i);
                    cell.setCellStyle(cellStyle);
                    if(j==1){
                        if(i==0){
                            cell.setCellValue("日期                   姓名");
                            //画线(由左上到右下的斜线)  在A1的第一个cell（单位  分类）加入一条对角线
                            HSSFPatriarch patriarch = (HSSFPatriarch) sheet.createDrawingPatriarch();
                            HSSFClientAnchor a = new HSSFClientAnchor(0, 255, 1023, 255, (short) 0, 0, (short) 0, 1);
                            HSSFSimpleShape shape1 = patriarch.createSimpleShape(a);
                            shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
                            shape1.setLineStyle(HSSFSimpleShape.LINESTYLE_SOLID);
                        }else{
                            if(i==holidayList.size()+1){
                                cell.setCellValue("正常出勤");
                            }else if(i==holidayList.size()+2){
                                cell.setCellValue("请假");
                            }else if(i==holidayList.size()+3){
                                cell.setCellValue("调休");
                            }else if(i==holidayList.size()+4){
                                cell.setCellValue("实际请假");
                            }else if(i==holidayList.size()+5){
                                cell.setCellValue("迟到");
                            }else if(i==holidayList.size()+6){
                                cell.setCellValue("缺卡");
                            }else {
                                cell.setCellValue(sdf1.format(holidayList.get(i-1).getDate()));
                            }
                        }
                    }else{
                        if(i==0){
                            cell.setCellValue(user.getUserName());
                        }else {
                            if(i<=holidayList.size()) {
                                List<TbPunchCard> punchCardList = baseMapper.getUserListByDate(user.getUserId(),sdf.format(holidayList.get(i-1).getDate()));
                                TbHoliday holiday = holidayList.get(i-1);
                                if(holiday.getType()==1){
                                    String msg = "";
                                    if(absenceMap!=null && absenceMap.size()>0){
                                        if(absenceMap.get(sdf.format(holiday.getDate()))!=null && absenceMap.get(sdf.format(holiday.getDate()))!=0d){
                                            totalHours += absenceMap.get(sdf.format(holiday.getDate()));
                                            if(sabbaticalMap!=null && sabbaticalMap.size()>0){
                                                if(sabbaticalMap.get(sdf.format(holiday.getDate()))!=null && sabbaticalMap.get(sdf.format(holiday.getDate()))!=0d){
                                                    if (sabbaticalMap.get(sdf.format(holiday.getDate())).equals(absenceMap.get(sdf.format(holiday.getDate())))){
                                                        msg += "调休"+sabbaticalMap.get(sdf.format(holiday.getDate()))+"小时";
                                                    }
                                                    if (sabbaticalMap.get(sdf.format(holiday.getDate()))<absenceMap.get(sdf.format(holiday.getDate()))){
                                                        BigDecimal b1 = new BigDecimal(absenceMap.get(sdf.format(holiday.getDate())).toString());
                                                        BigDecimal b2 = new BigDecimal(sabbaticalMap.get(sdf.format(holiday.getDate())).toString());
                                                        msg += "请假"+(new Double(b1.subtract(b2).doubleValue()))+"小时";
                                                        msg += "调休"+sabbaticalMap.get(sdf.format(holiday.getDate()))+"小时";
                                                    }
                                                    totalSabbatical += sabbaticalMap.get(sdf.format(holiday.getDate()));
                                                }else{
                                                    msg += "请假"+absenceMap.get(sdf.format(holiday.getDate()))+"小时";
                                                }
                                            }else {
                                                msg += "请假"+absenceMap.get(sdf.format(holiday.getDate()))+"小时";
                                            }
                                        }
                                    }

                                    if (punchCardList!=null && punchCardList.size()>0) {
                                        String str = "";
                                        for(TbPunchCard punchCard:punchCardList){
                                            str += punchCard.getState()+",";
                                            if(punchCard.getStatus()==1){
                                                if(punchCard.getState()==1){
                                                    msg += shift.getStartTime1();
                                                }
                                                if(punchCard.getState()==2){
                                                    msg += shift.getEndTime1();
                                                }
                                                if(punchCard.getState()==3){
                                                    msg += shift.getStartTime2();
                                                }
                                                if(punchCard.getState()==4){
                                                    msg += shift.getEndTime2();
                                                }
                                                msg += "缺卡";
                                                cell.setCellStyle(cellStyle2);
                                                missNum++;
                                            }
                                            if(punchCard.getStatus()==2){
                                                msg += "迟到"+sdf2.format(punchCard.getPunchCardTime());
                                                cell.setCellStyle(cellStyle1);
                                                lateNum++;
                                            }
                                        }
                                        if(!str.contains("1")){
                                            msg += "8:30无";
                                        }
                                        if(!str.contains("2")){
                                            msg += "11:30无";
                                        }
                                        if(!str.contains("3")){
                                            msg += "13:30无";
                                        }
                                        if(!str.contains("4")){
                                            msg += "18:00无";
                                        }
                                    }else {
                                        msg += "无";
                                    }
                                    cell.setCellValue(StringUtils.isEmpty(msg)?"√":msg);
                                    if(StringUtils.isEmpty(msg)||StringUtils.searchStr(msg,"迟到")>0||(StringUtils.searchStr(msg,"缺卡")<4&&StringUtils.searchStr(msg,"缺卡")>0)){
                                        normal++;
                                    }
                                }
                            }else if(i==holidayList.size()+1){
                                cell.setCellValue(normal+"天");
                            }else if(i==holidayList.size()+2){
                                cell.setCellValue(totalHours==0d?"":totalHours+"小时");
                            }else if(i==holidayList.size()+3){
                                cell.setCellValue(totalSabbatical==0d?"":totalSabbatical+"小时");
                            }else if(i==holidayList.size()+4){
                                BigDecimal b1 = new BigDecimal(totalHours.toString());
                                BigDecimal b2 = new BigDecimal(totalSabbatical.toString());
                                Double totalAbsence = new Double(b1.subtract(b2).doubleValue());
                                cell.setCellValue(totalAbsence==0d?"":totalAbsence+"小时");
                            }else if(i==holidayList.size()+5){
                                cell.setCellValue(lateNum==0?"":lateNum+"次");
                            }else if(i==holidayList.size()+6){
                                cell.setCellValue(missNum==0?"":missNum+"次");
                            }
                        }
                    }
                }
            }
            // 输出Excel文件
            OutputStream output = response.getOutputStream();
            response.reset();
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Type","application/force-download");
            response.setHeader("Content-disposition", "attachment; filename="+beginDate+"至"+endDate+"考勤信息.xls");    //filename =  文件名
            response.setContentType("application/msexcel");
            wb.write(output);
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void exportPunchCard(String beginDate, String endDate, HttpServletResponse response) {
        try{
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            SimpleDateFormat sdf1 = new SimpleDateFormat("MM-dd");
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sdf3 = new SimpleDateFormat("HH:mm:ss");
            SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFRow row = null;
            HSSFCell cell = null;
            // 建立新的sheet对象（excel的表单） 并设置sheet名字
            HSSFSheet sheet = wb.createSheet(beginDate+"至"+endDate+"打卡信息");
            sheet.setDefaultRowHeightInPoints(30);// 设置缺省列高sheet.setDefaultColumnWidth(20);//设置缺省列宽
            sheet.setDefaultColumnWidth(14);
            //----------------标题样式---------------------
            HSSFCellStyle titleStyle = wb.createCellStyle();        //标题样式
            titleStyle.setAlignment(HorizontalAlignment.CENTER);
            titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            Font ztFont = wb.createFont();
            ztFont.setItalic(false);                     // 设置字体为斜体字
            ztFont.setColor(Font.COLOR_NORMAL);            // 将字体设置为“红色”
            ztFont.setFontHeightInPoints((short)16);    // 将字体大小设置为18px
            ztFont.setFontName("宋体");             // 将“宋体”字体应用到当前单元格上
            ztFont.setBold(true);    //加粗
            titleStyle.setFont(ztFont);

            //----------------二级标题格样式----------------------------------
            HSSFCellStyle titleStyle2 = wb.createCellStyle();        //表格样式
            titleStyle2.setAlignment(HorizontalAlignment.CENTER);
            titleStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
            Font ztFont2 = wb.createFont();
            ztFont2.setItalic(false);                     // 设置字体为斜体字
            ztFont2.setColor(Font.COLOR_NORMAL);            // 将字体设置为“红色”
            ztFont2.setFontHeightInPoints((short)11);    // 将字体大小设置为18px
            ztFont2.setFontName("宋体");             // 字体应用到当前单元格上
            ztFont2.setBold(true);     //加粗
            //ztFont.setUnderline(Font.U_DOUBLE);         // 添加（Font.U_SINGLE单条下划线/Font.U_DOUBLE双条下划线）
            //ztFont.setStrikeout(true);                  // 是否添加删除线
            titleStyle2.setFont(ztFont2);

            //----------------单元格样式----------------------------------
            HSSFCellStyle cellStyle = wb.createCellStyle();        //表格样式
            cellStyle.setAlignment(HorizontalAlignment.CENTER);
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle.setBorderRight(BorderStyle.THIN);//右边框
            Font cellFont = wb.createFont();
            cellFont.setItalic(false);                     // 设置字体为斜体字
            cellFont.setColor(Font.COLOR_NORMAL);            // 将字体设置为“红色”
            cellFont.setFontHeightInPoints((short)10);    // 将字体大小设置为18px
            cellFont.setFontName("宋体");             // 字体应用到当前单元格上
            //cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            cellStyle.setFont(cellFont);
            cellStyle.setWrapText(true);//设置自动换行
            //----------------------------------------------------------

            //----------------单元格样式(迟到)----------------------------------
            HSSFCellStyle cellStyle1 = wb.createCellStyle();        //表格样式
            cellStyle1.setAlignment(HorizontalAlignment.CENTER);
            cellStyle1.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle1.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle1.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle1.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle1.setBorderRight(BorderStyle.THIN);//右边框
            cellStyle1.setFont(cellFont);
            cellStyle1.setWrapText(true);//设置自动换行
            //设置背景颜色
            cellStyle1.setFillForegroundColor(IndexedColors.ORANGE.getIndex());
            //solid 填充 foreground 前景色
            cellStyle1.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            //----------------------------------------------------------

            //----------------单元格样式(缺卡)----------------------------------
            HSSFCellStyle cellStyle2 = wb.createCellStyle();        //表格样式
            cellStyle2.setAlignment(HorizontalAlignment.CENTER);
            cellStyle2.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle2.setBorderBottom(BorderStyle.THIN); //下边框
            cellStyle2.setBorderLeft(BorderStyle.THIN);//左边框
            cellStyle2.setBorderTop(BorderStyle.THIN);//上边框
            cellStyle2.setBorderRight(BorderStyle.THIN);//右边框
            cellStyle2.setFont(cellFont);
            cellStyle2.setWrapText(true);//设置自动换行
            //设置背景颜色
            cellStyle2.setFillForegroundColor(IndexedColors.RED.getIndex());
            //solid 填充 foreground 前景色
            cellStyle2.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            //----------------------------------------------------------
            List<String> userList = userMapper.getUserIdList(new SysUser());
            List<TbHoliday> holidayList = holidayMapper.getListBybetween(beginDate,endDate);

            // ----------------------创建第一行---------------
            // 在sheet里创建第一行，参数为行索引(excel的行)，可以是0～65535之间的任何一个
            row = sheet.createRow(0);
            row.setHeight((short)(40*20));
            // 创建单元格（excel的单元格，参数为列索引，可以是0～255之间的任何一个
            cell = row.createCell(0);
            // 合并单元格CellRangeAddress构造参数依次表示起始行，截至行，起始列， 截至列
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, holidayList.size()));
            // 设置单元格内容
            cell.setCellValue(beginDate+"至"+endDate+"打卡记录");
            cell.setCellStyle(titleStyle);
            // ----------------------创建第二行（表头）---------------
            String startTime = sdf.format(holidayList.get(0).getDate());
            String endTime = sdf.format(holidayList.get(holidayList.size()-1).getDate());
            List<TbPunchCard> punchCardList = baseMapper.selectList(new QueryWrapper<TbPunchCard>().between("DATE(create_time)",startTime,endTime).orderByAsc("create_time"));
            SysUser user = null;
            for(int j=1;j<=userList.size()+1;j++){
                row = sheet.createRow(j);
                if (j>1){
                    row.setHeight((short)(50*20));
                    user = userMapper.selectUserById(Long.parseLong(userList.get(j-2)));
                }
                for(int i=0;i<=holidayList.size();i++){
                    cell = row.createCell(i);
                    cell.setCellStyle(cellStyle);
                    if(j==1){
                        if(i==0){
                            cell.setCellValue("日期                   姓名");
                            //画线(由左上到右下的斜线)  在A1的第一个cell（单位  分类）加入一条对角线
                            HSSFPatriarch patriarch = (HSSFPatriarch) sheet.createDrawingPatriarch();
                            HSSFClientAnchor a = new HSSFClientAnchor(0, 255, 1023, 255, (short) 0, 0, (short) 0, 1);
                            HSSFSimpleShape shape1 = patriarch.createSimpleShape(a);
                            shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
                            shape1.setLineStyle(HSSFSimpleShape.LINESTYLE_SOLID);
                        }else {
                            cell.setCellValue(sdf1.format(holidayList.get(i-1).getDate()));
                        }
                    }else{
                        if(i==0){
                            cell.setCellValue(user.getUserName());
                        } else {
                            TbHoliday holiday = holidayList.get(i-1);
                            if(holiday.getType()==1){
                                String msg = "";
                                for (TbPunchCard punchCard : punchCardList) {
                                    if (user.getUserId().equals(punchCard.getUserId()) && sdf.format(holiday.getDate()).equals(sdf.format(punchCard.getCreateTime()))) {
                                        if (StringUtils.isEmpty(msg)){
                                            if (punchCard.getPunchCardTime()!=null){
                                                msg += sdf3.format(punchCard.getPunchCardTime());
                                                if (punchCard.getStatus()==2){
                                                    msg += "(迟到)";
                                                }
                                            }else{
                                                if (punchCard.getStatus()==3){
                                                    msg += "请假";
                                                }
                                                if (punchCard.getStatus()==1){
                                                    if(punchCard.getState()==4){
                                                        TbAttendanceRecord attendanceRecord = attendanceMapper.selectOne(new QueryWrapper<TbAttendanceRecord>().eq("user_id", user.getDingUserId()).eq("DATE(work_date)",sdf.format(holiday.getDate())).ge("date_format(user_check_time,'%Y-%m-%d %H:%i:%S')",sdf.format(holiday.getDate())+" 18:31:00").orderByAsc("user_check_time").last("limit 1"));
                                                        if (attendanceRecord!=null){
                                                            msg += sdf3.format(attendanceRecord.getUserCheckTime());
                                                        }else {
                                                            msg += "缺卡";
                                                        }
                                                    }else {
                                                        msg += "缺卡";
                                                    }
                                                }
                                            }
                                        }else{
                                            if (punchCard.getPunchCardTime()!=null){
                                                msg += "\n" + sdf3.format(punchCard.getPunchCardTime());
                                                if (punchCard.getStatus()==2){
                                                    msg += "(迟到)";
                                                }
                                            }else{
                                                if (punchCard.getStatus()==3){
                                                    msg += "\n请假";
                                                }
                                                if (punchCard.getStatus()==1){
                                                    if(punchCard.getState()==4){
                                                        TbAttendanceRecord attendanceRecord = attendanceMapper.selectOne(new QueryWrapper<TbAttendanceRecord>().eq("user_id", user.getDingUserId()).eq("DATE(work_date)",sdf.format(holiday.getDate())).ge("date_format(user_check_time,'%Y-%m-%d %H:%i:%S')",sdf.format(holiday.getDate())+" 18:31:00").orderByAsc("user_check_time").last("limit 1"));
                                                        if (attendanceRecord!=null){
                                                            msg += "\n" + sdf3.format(attendanceRecord.getUserCheckTime());
                                                        }else {
                                                            msg += "\n缺卡";
                                                        }
                                                    }else {
                                                        msg += "\n缺卡";
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                cell.setCellValue(msg);
                            }
                        }
                    }
                }
            }
            // 输出Excel文件
            OutputStream output = response.getOutputStream();
            response.reset();
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            response.setHeader("Pragma", "no-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Content-Type","application/force-download");
            response.setHeader("Content-disposition", "attachment; filename="+beginDate+"至"+endDate+"考勤信息.xls");    //filename =  文件名
            response.setContentType("application/msexcel");
            wb.write(output);
            output.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @DataScope(deptAlias = "d")
    public List<Map<String, Object>> selectTodayAttendance(SysUser user) {
        return baseMapper.selectTodayAttendance(user);
    }
}
